package org.jpropeller.problem.impl;

import org.jpropeller.bean.impl.BeanDefault;
import org.jpropeller.problem.Problem;
import org.jpropeller.properties.Prop;

public class NumberProblem extends BeanDefault implements Problem {

	private final Prop<String> description;
	private final Prop<String> location;
	private final Prop<ProblemSeverity> severity;
	private final Prop<? extends Number> number;
	private final Prop<? extends Number> numberMin;
	private final Prop<? extends Number> numberMax;
	private final Prop<String> numberText;
	
	/**
	 * Create a new {@link IgnorableProblem}
	 * 
	 * @param description 	see {@link #description()}
	 * @param location 		see {@link #location()}
	 * @param severity 		see {@link #severity()}
	 * @param ignore 		Ignore this problem
	 */
	public NumberProblem(String description, String location,
			ProblemSeverity severity,final Prop<? extends Number> number,final Prop<? extends Number> numberMin,final Prop<? extends Number> numberMax) {
		this(description,location,severity,number,numberMin,numberMax,"Adjust "+number.getName().getString());
	}
	
	@Override
	public boolean equals(Object o)
	{
		if(o instanceof NumberProblem)
		{
			NumberProblem p=(NumberProblem)o;
			if((p.description.get()==null && description.get()==null) || (p.description.get().equals(description.get())))
			{
			if((p.location.get()==null && location.get()==null) || (p.location.get().equals(location.get())))
			{
			if((p.severity.get()==null && severity.get()==null) || (p.severity.get().equals(severity.get())))
			{
			if(p.number==number) // has to be the exact same prop
			{
			if((p.numberText.get()==null && numberText.get()==null) || (p.numberText.get().equals(numberText.get())))
			{
				return true;
			}
			}
			}
			}
			}
		}
		return false;
	}
	
	public boolean checkNumber(Number number)
	{
		if(number==null)
		{
			return false;
		}
		if(number instanceof Double)
		{
			return ((Double)number)>=(Double)numberMin.get() && ((Double)number)<=(Double)numberMax.get();
		}
		if(number instanceof Integer)
		{
			return ((Integer)number)>=(Integer)numberMin.get() && ((Integer)number)<=(Integer)numberMax.get();
		}
		return false;
	}

	/**
	 * Create a new {@link IgnorableProblem}
	 * 
	 * @param description 	see {@link #description()}
	 * @param location 		see {@link #location()}
	 * @param severity 		see {@link #severity()}
	 * @param ignore 		Ignore this problem
	 * @param ignoreText	Text associated with the ignore option
	 */
	public NumberProblem(String description, String location,
			ProblemSeverity severity,final Prop<? extends Number> number,final Prop<? extends Number> numberMin,final Prop<? extends Number> numberMax,
			String numberText) {
		super();
		this.severity = create(ProblemSeverity.class, "severity", severity);
		this.description = create("description", description);
		this.location = create("location", location);
		this.number = addProp(number);
		this.numberMin = addProp(numberMin);
		this.numberMax = addProp(numberMax);
		this.numberText= create("numberText", numberText);
	}

	public Prop<? extends Number> number(){return number;}
	public Prop<? extends Number> numberMin(){return numberMin;}
	public Prop<? extends Number> numberMax(){return numberMax;}
	public Prop<String> numberText(){return numberText;}

	@Override
	public Prop<String> description() {return description;}

	@Override
	public Prop<String> location() {return location;}

	@Override
	public Prop<ProblemSeverity> severity() {return severity;}
	
	@Override
	public String toString() {
		return description().get() + " at " + location().get() + ", " + severity().get();
	}

}
